///////////////////
// reflection.fx //
///////////////////

/////////////
// GLOBALS //
/////////////
matrix World;
matrix View;
matrix Projection;
matrix Reflection;

Texture2D ShaderTexture;
Texture2D ReflectionTexture;


///////////////////
// SAMPLE STATES //
///////////////////
SamplerState SampleType
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};

//////////////
// TYPEDEFS //
//////////////
struct VS_IN
{
	float4 position     : POSITION;         //posizione
    float3 norm         : NORMAL;           //normale
    float3 tan          : TANGENT;          //tangente
    float3 binorm       : BINORMAL;         //binormale
    float2 tex          : TEXCOORD;			//Coordinate texture
};

struct VS_OUT
{
    float4 position : SV_POSITION;
    float2 tex : TEXCOORD0;
   	float4 reflectionPosition : TEXCOORD1;
};

////////////////////////////////////////////////////////////////////////////////
// Vertex Shader
////////////////////////////////////////////////////////////////////////////////
VS_OUT ReflectionVertexShader(VS_IN input)
{
	VS_OUT output = (VS_OUT)0;  
	//Vertex into world space
	output.position = mul(input.position, World);
	output.position = mul(output.position, View);
	output.position = mul(output.position, Projection);

	output.tex = input.tex;


	//Calculate the reflected position
	output.reflectionPosition = mul(input.position, World);
	output.reflectionPosition = mul(output.reflectionPosition, Reflection);
	output.reflectionPosition = mul(output.reflectionPosition, Projection);
    
	return output;
}

float4 ReflectionPixelShader(VS_OUT input): SV_Target
{
	float4 textureColor;
	float2 reflectTexCoord;
	float4 reflectionColor;
	float4 color;

	textureColor = ShaderTexture.Sample(SampleType, input.tex);

	// Here reflectTexCoord.x and .y are in range [-1, 1]. Adjust them to range [0, 1] and
	// calculate the projected reflection texture coordinates.
    reflectTexCoord.x = input.reflectionPosition.x / input.reflectionPosition.w / 2.0f + 0.5f;
	reflectTexCoord.y = -input.reflectionPosition.y / input.reflectionPosition.w / 2.0f + 0.5f;

	reflectionColor = ReflectionTexture.Sample(SampleType, reflectTexCoord);

	// Linear interpolation between the two textures.
	//0: no reflection
	//1: perfect reflection
	color = lerp(textureColor, reflectionColor, 0.90f);

	return color;
}

////////////////////////////////////////////////////////////////////////////////
// Technique
////////////////////////////////////////////////////////////////////////////////
technique10 ReflectionTechnique
{
    pass pass0
    {
        SetVertexShader(CompileShader(vs_4_0, ReflectionVertexShader()));
        SetPixelShader(CompileShader(ps_4_0, ReflectionPixelShader()));
        SetGeometryShader(NULL);
    }
}